use warp::{Filter, Reply};
use std::net::SocketAddr;
use log::{info, error, warn};

/// 使用Tauri Asset Resolver的HTTP服务器
/// 这种方式特别适合移动端应用，因为资源被打包在应用内部
pub async fn start_asset_server(app: tauri::AppHandle, port: u16) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    info!("启动Asset服务器，端口: {}", port);
    
    // 克隆app handle用于闭包
    let app_clone = app.clone();
    
    // 静态文件处理器 - 使用Tauri的asset resolver
    let asset_route = warp::path::tail()
        .map(move |tail: warp::path::Tail| {
            let path = tail.as_str();
            let asset_path = if path.is_empty() { 
                "index.html" 
            } else { 
                path 
            };
            
            info!("请求资源: {}", asset_path);
            
            match app_clone.asset_resolver().get(asset_path.to_string()) {
                Some(asset) => {
                    info!("找到资源: {}, MIME类型: {}", asset_path, asset.mime_type);
                    warp::reply::with_header(
                        asset.bytes, 
                        "content-type", 
                        asset.mime_type
                    ).into_response()
                },
                None => {
                    warn!("资源未找到: {}", asset_path);
                    
                    // 如果是SPA路由，返回index.html
                    if !asset_path.contains('.') {
                        match app_clone.asset_resolver().get("index.html".to_string()) {
                            Some(index_asset) => {
                                info!("返回index.html用于SPA路由: {}", asset_path);
                                warp::reply::with_header(
                                    index_asset.bytes,
                                    "content-type",
                                    "text/html"
                                ).into_response()
                            },
                            None => {
                                error!("index.html也未找到");
                                warp::reply::with_status(
                                    "Not Found", 
                                    warp::http::StatusCode::NOT_FOUND
                                ).into_response()
                            }
                        }
                    } else {
                        warp::reply::with_status(
                            "Not Found", 
                            warp::http::StatusCode::NOT_FOUND
                        ).into_response()
                    }
                }
            }
        });
    
    // 健康检查路由
    let health_route = warp::path("health")
        .map(|| {
            info!("健康检查请求");
            warp::reply::with_status("Asset Server OK", warp::http::StatusCode::OK)
        });
    
    // API路由 - 用于移动端特殊需求
    let mobile_api = warp::path("api")
        .and(warp::path("mobile"))
        .and(warp::path("info"))
        .map(|| {
            let info = serde_json::json!({
                "server_type": "tauri_asset_server",
                "version": "1.0.0",
                "supported_features": ["draw_guess_mobile", "websocket_connection"],
                "endpoints": {
                    "websocket": "ws://[IP]:3032",
                    "health": "/health"
                }
            });
            warp::reply::json(&info)
        });
    
    // 组合所有路由
    let routes = health_route
        .or(mobile_api)
        .or(asset_route);
    
    let addr: SocketAddr = ([0, 0, 0, 0], port).into();
    
    // 检查端口是否可用
    if let Err(e) = std::net::TcpListener::bind(addr) {
        error!("Asset服务器绑定端口 {} 失败: {}", port, e);
        return Err(format!("端口 {} 被占用或无法绑定: {}", port, e).into());
    }
    
    info!("Asset服务器成功启动在 http://0.0.0.0:{}", port);
    info!("DrawGuessMobile可通过以下方式访问:");
    info!("  - 直接访问: http://[IP]:{}/", port);
    info!("  - 移动端路由: http://[IP]:{}/#/drawguess", port);
    
    warp::serve(routes)
        .run(addr)
        .await;
    
    Ok(())
}

/// 启动混合服务器 - 同时支持文件系统和Asset Resolver
pub async fn start_hybrid_server(
    app: tauri::AppHandle, 
    port: u16, 
    fallback_static_dir: Option<std::path::PathBuf>
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    info!("启动混合服务器，端口: {}", port);
    
    let app_clone = app.clone();
    
    // 混合资源处理器
    let hybrid_route = warp::path::tail()
        .map(move |tail: warp::path::Tail| {
            let path = tail.as_str();
            let asset_path = if path.is_empty() { "index.html" } else { path };
            
            // 首先尝试从Tauri Asset Resolver获取
            match app_clone.asset_resolver().get(asset_path.to_string()) {
                Some(asset) => {
                    info!("从Asset Resolver获取: {}", asset_path);
                    warp::reply::with_header(
                        asset.bytes, 
                        "content-type", 
                        asset.mime_type
                    ).into_response()
                },
                None => {
                    info!("Asset Resolver中未找到: {}, 尝试文件系统", asset_path);
                    
                    // 如果Asset Resolver中没有，尝试从文件系统读取
                    if let Some(ref static_dir) = fallback_static_dir {
                        let file_path = static_dir.join(asset_path);
                        if file_path.exists() {
                            match std::fs::read(&file_path) {
                                Ok(content) => {
                                    let mime_type = mime_guess::from_path(&file_path)
                                        .first_or_octet_stream()
                                        .to_string();
                                    info!("从文件系统获取: {:?}", file_path);
                                    return warp::reply::with_header(
                                        content,
                                        "content-type",
                                        mime_type
                                    ).into_response();
                                },
                                Err(e) => {
                                    error!("读取文件失败 {:?}: {}", file_path, e);
                                }
                            }
                        }
                    }
                    
                    // 如果都没找到，对于SPA路由返回index.html
                    if !asset_path.contains('.') {
                        match app_clone.asset_resolver().get("index.html".to_string()) {
                            Some(index_asset) => {
                                info!("返回index.html用于SPA路由: {}", asset_path);
                                warp::reply::with_header(
                                    index_asset.bytes,
                                    "content-type",
                                    "text/html"
                                ).into_response()
                            },
                            None => {
                                warp::reply::with_status(
                                    "Not Found", 
                                    warp::http::StatusCode::NOT_FOUND
                                ).into_response()
                            }
                        }
                    } else {
                        warp::reply::with_status(
                            "Not Found", 
                            warp::http::StatusCode::NOT_FOUND
                        ).into_response()
                    }
                }
            }
        });
    
    let addr: SocketAddr = ([0, 0, 0, 0], port).into();
    
    info!("混合服务器启动在 http://0.0.0.0:{}", port);
    warp::serve(hybrid_route)
        .run(addr)
        .await;
    
    Ok(())
}
